package cn.com.gridinfo.sooc.core.course.classes.fragment.videocontrol;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.jeremy.arad.utils.StringUtils;
import com.pili.pldroid.player.IMediaController;
import com.pili.pldroid.player.widget.PLVideoTextureView;

import java.util.Locale;

import cn.com.gridinfo.sooc.R;

/**
 * You can write a custom MediaController instead of this class
 * A MediaController widget must implement all the interface defined by com.pili.pldroid.player.IMediaController
 */
public class MediaController extends FrameLayout implements IMediaController {

    private static final String TAG = "PLMediaController";
    private IMediaController.MediaPlayerControl mPlayer;
    private Context mContext;
    private PopupWindow mWindow;
    private int mAnimStyle;
    private View mAnchor;
    private View mRoot;
//    private ProgressBar mProgress;
//    private TextView mEndTime, mCurrentTime;
    private long mDuration;
    private boolean mShowing;
    private boolean mDragging;
    private boolean mInstantSeeking = true;
    private static int sDefaultTimeout = 3000;
    private static final int SEEK_TO_POST_DELAY_MILLIS = 200;

    private static final int FADE_OUT = 1;
    private static final int SHOW_PROGRESS = 2;
    private boolean mFromXml = false;
//    private ImageButton mPauseButton;
//    private ImageButton mFfwdButton;
//    private ImageButton mRewButton;
//    private ImageButton mNextButton;
//    private ImageButton mPrevButton;

    private boolean mUseFastForward;

//    private static final int IC_MEDIA_PAUSE_ID = Resources.getSystem().getIdentifier("ic_media_pause","drawable", "android");
//    private static final int IC_MEDIA_PLAY_ID = Resources.getSystem().getIdentifier("ic_media_play","drawable", "android");
//    private static final int MEDIA_CONTROLLER_ID = Resources.getSystem().getIdentifier("media_controller", "layout", "android");
//    private static final int PRV_BUTTON_ID = Resources.getSystem().getIdentifier("prev","id", "android");
//    private static final int FFWD_BUTTON_ID = Resources.getSystem().getIdentifier("ffwd","id", "android");
//    private static final int NEXT_BUTTON_ID = Resources.getSystem().getIdentifier("next","id", "android");
//    private static final int REW_BUTTON_ID = Resources.getSystem().getIdentifier("rew","id", "android");
//    private static final int PAUSE_BUTTON_ID = Resources.getSystem().getIdentifier("pause","id", "android");
//    private static final int MEDIACONTROLLER_PROGRESS_ID = Resources.getSystem().getIdentifier("mediacontroller_progress","id", "android");
//    private static final int END_TIME_ID = Resources.getSystem().getIdentifier("time","id", "android");
//    private static final int CURRENT_TIME_ID = Resources.getSystem().getIdentifier("time_current","id", "android");

    private AudioManager mAM;
    private Runnable mLastSeekBarRunnable;
    private boolean mDisableProgress = false;



    private ImageButton backArrowBtn;//返回；
    private TextView videoNameTv;//视频名称
    private ImageButton playOrPauseBtn;//暂停播放按钮
    private ImageButton minOrMaxScreenBtn;//最大化最小化视频按钮

    private TextView totalTimeTv;//总时间
    private TextView currTimeTv;//当前播放时间

    private SeekBar seekbarPro;//进度条

    private RelativeLayout rl_title;//全屏是头部控制条

    private boolean  isFullScreen = false;//默认小屏


    private PLVideoTextureView mVideoView;

    FrameLayout container;

    private Activity activity;

    int videoHeight;
    String videoName;


    private MediaPauseOrPlayListener mediaPauseOrPlayListener;

    public MediaController(Context context, AttributeSet attrs) {
        super(context, attrs);
        mRoot = this;
        mFromXml = true;
        initController(context);
    }

    public MediaController(Context context) {
        super(context);
        if (!mFromXml && initController(context))
            initFloatingWindow();
    }

    public MediaController(Context context, boolean useFastForward, boolean disableProgressBar) {
        this(context);
        mUseFastForward = useFastForward;
        mDisableProgress = disableProgressBar;
    }


    /**
     * 控制器构造函数
     * @param context  上下文
     * @param fromXml
     * @param container  视频容器布局
     * @param videoView  视频布局
     * @param videoHeight  视频高度
     * @param videoName  视频名称
     */
    public MediaController(Context context, boolean fromXml, View container, PLVideoTextureView videoView, int videoHeight, String videoName) {
        super(context);
        initController(context);
        this.activity = (Activity)context;
        this.mVideoView = videoView;
        this.videoName = videoName;
        this.videoHeight = videoHeight;
        mFromXml = fromXml;
        mRoot = makeControllerView();//这个地方的FrameLayout.LayoutpParams是因为布局文件中要把MediaController的视图作为childView加到一个FrameLayout中去
        LayoutParams p = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);//想怎样布局MediaController就尽情的发挥这个LayoutParams吧
        p.gravity = Gravity.BOTTOM;
        mRoot.setLayoutParams(p);
        ((FrameLayout)container).addView(mRoot);

    }


    public MediaController(Context context, boolean useFastForward) {
        this(context);
        mUseFastForward = useFastForward;
    }

    private boolean initController(Context context) {
        mUseFastForward = true;
        mContext = context.getApplicationContext();
        mAM = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        return true;
    }

    @Override
    public void onFinishInflate() {
        if (mRoot != null)
            initControllerView(mRoot);
        super.onFinishInflate();
    }

    private void initFloatingWindow() {
        mWindow = new PopupWindow(mContext);
        mWindow.setFocusable(false);
        mWindow.setBackgroundDrawable(null);
        mWindow.setOutsideTouchable(true);
        mAnimStyle = android.R.style.Animation;
    }

//    /**
//     * Create the view that holds the widgets that control playback. Derived
//     * classes can override this to create their own.
//     *
//     * @return The controller view.
//     */
//    protected View makeControllerView() {
//        return ((LayoutInflater) mContext
//                .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(MEDIA_CONTROLLER_ID, this);
//    }

    /**
     * Create the view that holds the widgets that control playback. Derived
     * classes can override this to create their own.
     *
     * @return The controller view.
     */
    protected View makeControllerView() {
        return ((LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.mymediacontroller, this);
    }



    private void initControllerView(View v) {
        // By default these are hidden.
        rl_title =(RelativeLayout)v.findViewById(R.id.rl_title);//头部控制条
        if(rl_title!=null){
            if(isFullScreen){
                rl_title.setVisibility(View.VISIBLE);
            }else {
                rl_title.setVisibility(View.GONE);
            }
        }
        backArrowBtn = (ImageButton) v.findViewById(R.id.mediacontroller_top_back);
        if (backArrowBtn != null) {
            backArrowBtn.setOnClickListener(minOrMaxListener);
        }
        videoNameTv = (TextView) v.findViewById(R.id.file_name);
        if (videoNameTv != null) {
            videoNameTv.setText(videoName);
        }

        minOrMaxScreenBtn = (ImageButton) v.findViewById(R.id.mediacontroller_max);
        if (minOrMaxScreenBtn != null) {
            minOrMaxScreenBtn.setOnClickListener(minOrMaxListener);

        }

//        mRewButton = (ImageButton) v.findViewById(REW_BUTTON_ID);
//        if (mRewButton != null) {
//            mRewButton.setOnClickListener(mRewListener);
//            if (!mFromXml) {
//                mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
//            }
//        }
        playOrPauseBtn = (ImageButton) v.findViewById(R.id.mediacontroller_play_pause);
        if (playOrPauseBtn != null) {
            playOrPauseBtn.requestFocus();
            playOrPauseBtn.setOnClickListener(mPauseListener);
        }

        seekbarPro = (SeekBar) v.findViewById(R.id.mediacontroller_seekbar);
        if (seekbarPro != null) {

            seekbarPro.setOnSeekBarChangeListener(mSeekListener);
            seekbarPro.setThumbOffset(1);

            seekbarPro.setMax(1000);
            seekbarPro.setEnabled(!mDisableProgress);
        }

        totalTimeTv = (TextView) v.findViewById(R.id.mediacontroller_time_total);
        currTimeTv = (TextView) v.findViewById(R.id.mediacontroller_time_current);
    }
    /**
     * Control the action when the seekbar dragged by user
     *
     * @param seekWhenDragging
     * True the media will seek periodically
     */
    public void setInstantSeeking(boolean seekWhenDragging) {
        mInstantSeeking = seekWhenDragging;
    }

    private void disableUnsupportedButtons() {
        try {
            if (playOrPauseBtn != null && !mPlayer.canPause())
                playOrPauseBtn.setEnabled(false);
        } catch (IncompatibleClassChangeError ex) {
        }
    }

    /**
     * <p>
     * Change the animation style resource for this controller.
     * </p>
     *
     * <p>
     * If the controller is showing, calling this method will take effect only
     * the next time the controller is shown.
     * </p>
     *
     * @param animationStyle
     * animation style to use when the controller appears and disappears.
     * Set to -1 for the default animation, 0 for no animation,
     * or a resource identifier for an explicit animation.
     *
     */
    public void setAnimationStyle(int animationStyle) {
        mAnimStyle = animationStyle;
    }

    public interface OnShownListener {
        public void onShown();
    }

    private OnShownListener mShownListener;

    public void setOnShownListener(OnShownListener l) {
        mShownListener = l;
    }

    public interface OnHiddenListener {
        public void onHidden();
    }

    private OnHiddenListener mHiddenListener;

    public void setOnHiddenListener(OnHiddenListener l) {
        mHiddenListener = l;
    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            long pos;
            switch (msg.what) {
                case FADE_OUT:
                    hide();
                    break;
                case SHOW_PROGRESS:
                    pos = setProgress();
                    if (!mDragging && mShowing) {
                        msg = obtainMessage(SHOW_PROGRESS);
                        sendMessageDelayed(msg, 1000 - (pos % 1000));
                        updatePausePlay();
                    }
                    break;
            }
        }
    };

    private long setProgress() {
        if (mPlayer == null || mDragging)
            return 0;

        long position = mPlayer.getCurrentPosition();
        long duration = mPlayer.getDuration();
        if (seekbarPro != null) {
            if (duration > 0) {
                long pos = 1000L * position / duration;
                seekbarPro.setProgress((int) pos);
            }
            int percent = mPlayer.getBufferPercentage();
            seekbarPro.setSecondaryProgress(percent * 10);
        }

        mDuration = duration;

        if (totalTimeTv != null)
            totalTimeTv.setText(generateTime(mDuration));
        if (currTimeTv != null)
            currTimeTv.setText(generateTime(position));

        return position;
    }

    private static String generateTime(long position) {
        int totalSeconds = (int) (position / 1000);

        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        if (hours > 0) {
            return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
                    seconds).toString();
        } else {
            return String.format(Locale.US, "%02d:%02d", minutes, seconds)
                    .toString();
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        show(sDefaultTimeout);
        return true;
    }

    @Override
    public boolean onTrackballEvent(MotionEvent ev) {
        show(sDefaultTimeout);
        return false;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (event.getRepeatCount() == 0
                && (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
                || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) {
            doPauseResume();
            show(sDefaultTimeout);
            if (playOrPauseBtn != null)
                playOrPauseBtn.requestFocus();
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
            if (mPlayer.isPlaying()) {
                mediaPauseOrPlayListener.pauseVideo();
                updatePausePlay();
            }
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_BACK
                || keyCode == KeyEvent.KEYCODE_MENU) {
            hide();
            return true;
        } else {
            show(sDefaultTimeout);
        }
        return super.dispatchKeyEvent(event);
    }

    private OnClickListener mPauseListener = new OnClickListener() {
        public void onClick(View v) {
            doPauseResume();
            show(sDefaultTimeout);
        }
    };

    private void updatePausePlay() {
        if (mRoot == null || playOrPauseBtn == null)
            return;

        if (mPlayer.isPlaying())
            playOrPauseBtn.setImageResource(R.mipmap.mediacontroller_pause);
        else
            playOrPauseBtn.setImageResource(R.mipmap.mediacontroller_play);
    }

    private void doPauseResume() {
        if (mPlayer.isPlaying())
            mediaPauseOrPlayListener.pauseVideo();
        else
            mediaPauseOrPlayListener.startVideo();
        updatePausePlay();
    }

    private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {

        public void onStartTrackingTouch(SeekBar bar) {
            mDragging = true;
            show(3600000);
            mHandler.removeMessages(SHOW_PROGRESS);
            if (mInstantSeeking)
                mAM.setStreamMute(AudioManager.STREAM_MUSIC, true);
        }

        public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
            if (!fromuser)
                return;

            final long newposition = (mDuration * progress) / 1000;
            String time = generateTime(newposition);
            if (mInstantSeeking) {
                mHandler.removeCallbacks(mLastSeekBarRunnable);
                mLastSeekBarRunnable = new Runnable() {
                    @Override
                    public void run() {
                        //防止拖到最后卡死
                        if(newposition>=mDuration){
                            mPlayer.seekTo(mDuration-2000);
                        }else {
                            mPlayer.seekTo(newposition);
                        }
                    }
                };
                mHandler.postDelayed(mLastSeekBarRunnable, SEEK_TO_POST_DELAY_MILLIS);
            }
            if (currTimeTv != null)
                currTimeTv.setText(time);
        }

        public void onStopTrackingTouch(SeekBar bar) {
            if (!mInstantSeeking)
                mPlayer.seekTo((int)(mDuration * bar.getProgress()) / 1000);

            show(sDefaultTimeout);
            mHandler.removeMessages(SHOW_PROGRESS);
            mAM.setStreamMute(AudioManager.STREAM_MUSIC, false);
            mDragging = false;
            mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000);
        }
    };
    private OnClickListener minOrMaxListener = new OnClickListener() {
        public void onClick(View v) {
            //当前是全屏变成小屏
            if(isFullScreen){
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//强制视频竖屏
            }else{

                //强制手机横向
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);

            }
        }
    };



    /**
     * 设置全屏
     */
    public void setFullScreen() {
        // 设置全屏的相关属性，获取当前的屏幕状态，然后设置全屏
        activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // 全屏下的状态码：1098974464
        // 窗口下的状态吗：1098973440
    }

    /**
     * 退出全屏
     */
    public void quitFullScreen() {
        // 声明当前屏幕状态的参数并获取
        final WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
        attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
        activity.getWindow().setAttributes(attrs);
        activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

    /**
     * 视频最小化
     */
    public void minScreen(){
        isFullScreen = false;
        quitFullScreen();//推出全屏

        rl_title.setVisibility(View.GONE);//隐藏控制栏头部
        minOrMaxScreenBtn.setImageResource(R.mipmap.video_fullscreen);
//        mVideoView.setDisplayAspectRatio(PLVideoTextureView.ASPECT_RATIO_16_9);
        mVideoView.getLayoutParams().height = videoHeight ;//设置视频最小化高度
        mVideoView.getLayoutParams().width = StringUtils.getScreenWidth(activity);//视频宽度
    }

    /**
     * 视频最大化 全屏
     */
    public void maxScreen(){
        setFullScreen();//全屏

        rl_title.setVisibility(View.VISIBLE);//显示控制栏头部
        minOrMaxScreenBtn.setImageResource(R.mipmap.video_smallscreen);
        LayoutParams cparams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        cparams.gravity = Gravity.CENTER;
        mVideoView.setLayoutParams(cparams);
        isFullScreen = true;
//        mVideoView.setDisplayAspectRatio(PLVideoTextureView.ASPECT_RATIO_FIT_PARENT);//设置视频全屏
    }


    private OnClickListener mRewListener = new OnClickListener() {
        public void onClick(View v) {
            int pos = (int)mPlayer.getCurrentPosition();
            pos -= 5000; // milliseconds
            mPlayer.seekTo(pos);
            setProgress();

            show(sDefaultTimeout);
        }
    };

    private OnClickListener mFfwdListener = new OnClickListener() {
        public void onClick(View v) {
            int pos = (int)mPlayer.getCurrentPosition();
            pos += 15000; // milliseconds
            mPlayer.seekTo(pos);
            setProgress();

            show(sDefaultTimeout);
        }
    };

    /**
     * Set the view that acts as the anchor for the control view.
     *
     * - This can for example be a VideoView, or your Activity's main view.
     * - AudioPlayer has no anchor view, so the view parameter will be null.
     *
     * @param view
     * The view to which to anchor the controller when it is visible.
     */
    @Override
    public void setAnchorView(View view) {
        mAnchor = view;
        if (mAnchor == null) {
            sDefaultTimeout = 0; // show forever
        }
        if (!mFromXml) {
            removeAllViews();
            mRoot = makeControllerView();
            mWindow.setContentView(mRoot);
            mWindow.setWidth(LayoutParams.MATCH_PARENT);
            mWindow.setHeight(LayoutParams.WRAP_CONTENT);
        }
        initControllerView(mRoot);
    }

    @Override
    public void setMediaPlayer(MediaPlayerControl player) {
        mPlayer = player;
        updatePausePlay();
    }

    @Override
    public void show() {
        show(sDefaultTimeout);
    }

    /**
     * Show the controller on screen. It will go away automatically after
     * 'timeout' milliseconds of inactivity.
     *
     * @param timeout
     * The timeout in milliseconds. Use 0 to show the controller until hide() is called.
     */
    @Override
    public void show(int timeout) {
        if (!mShowing) {
            if (mAnchor != null && mAnchor.getWindowToken() != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    mAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                }
            }
            if (playOrPauseBtn != null)
                playOrPauseBtn.requestFocus();
            disableUnsupportedButtons();

            if (mFromXml) {
                setVisibility(View.VISIBLE);
            } else {
                int[] location = new int[2];

                if (mAnchor != null) {
                    mAnchor.getLocationOnScreen(location);
                    Rect anchorRect = new Rect(location[0], location[1],
                            location[0] + mAnchor.getWidth(), location[1]
                            + mAnchor.getHeight());

                    mWindow.setAnimationStyle(mAnimStyle);
                    mWindow.showAtLocation(mAnchor, Gravity.BOTTOM,
                            anchorRect.left, 0);
                } else {
                    Rect anchorRect = new Rect(location[0], location[1],
                            location[0] + mRoot.getWidth(), location[1]
                            + mRoot.getHeight());

                    mWindow.setAnimationStyle(mAnimStyle);
                    mWindow.showAtLocation(mRoot, Gravity.BOTTOM,
                            anchorRect.left, 0);
                }
            }
            mShowing = true;
            if (mShownListener != null)
                mShownListener.onShown();
        }
        updatePausePlay();
        mHandler.sendEmptyMessage(SHOW_PROGRESS);

        if (timeout != 0) {
            mHandler.removeMessages(FADE_OUT);
            mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT),
                    timeout);
        }
    }

    @Override
    public boolean isShowing() {
        return mShowing;
    }

    @Override
    public void hide() {
        if (mShowing) {
            if (mAnchor != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    //mAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
                }
            }
            try {
                mHandler.removeMessages(SHOW_PROGRESS);
                if (mFromXml)
                    setVisibility(View.GONE);
                else
                    mWindow.dismiss();
            } catch (IllegalArgumentException ex) {
                Log.d(TAG, "MediaController already removed");
            }
            mShowing = false;
            if (mHiddenListener != null)
                mHiddenListener.onHidden();
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        if (playOrPauseBtn != null) {
            playOrPauseBtn.setEnabled(enabled);
        }
//        if (mFfwdButton != null) {
//            mFfwdButton.setEnabled(enabled);
//        }
//        if (mRewButton != null) {
//            mRewButton.setEnabled(enabled);
//        }
        if (seekbarPro != null && !mDisableProgress)
            seekbarPro.setEnabled(enabled);
        disableUnsupportedButtons();
        super.setEnabled(enabled);
    }


    /**
     * 视频播放暂停按钮监听
     */
   public interface MediaPauseOrPlayListener {

        void startVideo();

        void pauseVideo();
    }

    public void setMediaPauseOrPlay(MediaPauseOrPlayListener mediaPauseOrPlayListener) {
        this.mediaPauseOrPlayListener = mediaPauseOrPlayListener;
    }
}
